------------------------------------------------------------
-- 背包

-- addItem 			添加道具
-- delItem 			删除道具
-- sendItemGetList 	通用道具获得界面
-- checkItemCnt 	检查道具数量是否足够，否则提示
-- getItemCnt 		返回道具数量
------------------------------------------------------------

local EquipExcel = require("excel.equip").equip
local ItemExcel = require("excel.item").item
local FuwenExcel = require("excel.fuwen").fuwen
local ItemBuyExcel = require("excel.item").buy
local ItemComonBuyExcel = require("excel.item").commonBuy
local Log = require("common.Log")
local LogDefine = require("common.LogDefine")
local Lang = require("common.Lang")
local Util = require("common.Util")
local ObjHuman = require("core.ObjHuman")
local Msg = require("core.Msg")
local Broadcast = require("broadcast.Broadcast")
local Grid = require("bag.Grid")
local ItemLogic = require("bag.ItemLogic")
local ItemDefine = require("bag.ItemDefine")
local ChengjiuDefine = require("chengjiu.ChengjiuDefine")
local ChengjiuLogic = require("chengjiu.ChengjiuLogic")
local FuwenLogic = require("fuwen.FuwenLogic")
local MiddleOption = require("middle.MiddleOption")
local RoleSystemLogic = require("roleSystem.RoleSystemLogic")
local RoleSystemDefine = require("roleSystem.RoleSystemDefine")
local EquipLogic = require("equip.EquipLogic")
local YunYingLogic = require("yunying.YunYingLogic")
local PanelDefine = require("broadcast.PanelDefine")
local HeroGrowUp = require("absAct.HeroGrowUp")

local ITEM_MOMENT_ADD_LIST = {}
ADDITEM_TYPE_1 = 1   --顺序 不整合添加道具 非1 表示整合所有相同的道具数量
ADDITEM_TYPE_2 = 2   

function updateMomentItem(type, itemID, itemCnt, quality)
	if type == ADDITEM_TYPE_1 then
        local len = #ITEM_MOMENT_ADD_LIST + 1
		ITEM_MOMENT_ADD_LIST[len] = {}
		ITEM_MOMENT_ADD_LIST[len][1] = itemID
		ITEM_MOMENT_ADD_LIST[len][2] = itemCnt
        ITEM_MOMENT_ADD_LIST[len][3] = quality
	else
		ITEM_MOMENT_ADD_LIST[itemID] = ITEM_MOMENT_ADD_LIST[itemID] or 0
		ITEM_MOMENT_ADD_LIST[itemID] = ITEM_MOMENT_ADD_LIST[itemID] + itemCnt
	end	
end

-- 防止有报错 导致的 别的玩家 额外获得道具  在使用 通用的 添加之前 清除一次
function cleanMomentItemList()
	Util.cleanTable(ITEM_MOMENT_ADD_LIST)
end

function addMomentItemList(human, logType, noSend)
	addItemList(human, ITEM_MOMENT_ADD_LIST, logType, noSend)
	cleanMomentItemList()
end

-- 通用道具添加 {[1] = {id, cnt}, [2] = {id,cnt}} or {[itemID] = itemCnt}  配表复杂 各自接口下自己for 添加
function addItemList(human,  list, logType, noSend)
	if not list or next(list) == nil then return end
	if list[1] and list[1][1] then
		for _, item in ipairs(list) do
			addItem(human, item[1], item[2], logType, noSend, item[3])
		end
	else
		for itemID, itemCnt in pairs(list) do
			addItem(human, itemID, itemCnt, logType, noSend)		
		end
	end

	sendItemGetList(human, list, logType)
end

-- 增加装备，道具
function addItem(human, id, cnt, logType, noSend, otherData)
	if cnt < 1 then return end
	local itemConfig = ItemDefine.getConfig(id)
	if not itemConfig then return end	
	if not LogDefine.DEFINE[logType] or not LogDefine.TYPE["item"] then
		assert()
	end

	MiddleOption.addItem(human, id, cnt, logType)
	if handlerSpObj(human, id, cnt, logType) then
		return
	end
    	
	if handleFuwen(human, id, cnt, logType) then
		return
	end

    -- 装备走另外的逻辑
    if handleEquipAdd(human, id, cnt, logType, otherData) then

		return
	end

	local oldCnt = human.db.bag[id] or 0
	local newCnt = math.min(oldCnt + cnt, ItemDefine.BAG_ITEM_MAX_CNT)
	human.db.bag[id] = newCnt
	
	if not noSend then
		sendChange(human, id, oldCnt < 1)
	end	
	Log.write(Log.LOGID_OSS_ITEM, human.db._id, human.db.account, human.db.name, human.db.lv, 
		LogDefine.DEFINE[logType] + LogDefine.TYPE["item"] , id, cnt, newCnt)
		
    -- 如果道具为公会贡献，记录到当日累计贡献中
    if id == ItemDefine.ITEM_UNION_COIN_ID then
        human.db.dailyBanggong = human.db.dailyBanggong or 0
        human.db.dailyBanggong = human.db.dailyBanggong + cnt
        human.db.totalBanggong = human.db.totalBanggong or 0
        human.db.totalBanggong = human.db.totalBanggong + cnt
    end
        
    -- 根据道具触发红点
	checkDotByID(human,id)

	return true
end

function checkDotByID(human,id)
    local itemConfig = ItemDefine.getConfig(id)
    local dotTb = itemConfig.dot
    local len = #dotTb
    for i = 1,len do
        RoleSystemLogic.onDot(human, dotTb[i])
    end
end


-- 根据id删除
function delItem(human, id, cnt, logType, noSend, byId, byCnt)
	if cnt < 1 then return end
	local itemConfig = ItemExcel[id]
	if not itemConfig then return end	
	if not LogDefine.DEFINE[logType] or not LogDefine.TYPE["item"] then
		assert()
	end	
	if id == ItemDefine.ITEM_JINBI_ID  then 
		return ObjHuman.updateJinbi(human, -cnt, logType, byId, byCnt)
	elseif id == ItemDefine.ITEM_ZUANSHI_ID then 
		return ObjHuman.decZuanshi(human, -cnt, logType, byId, byCnt)
    elseif id == ItemDefine.ITEM_FRIEND_ID then 
		return ObjHuman.updateFriendHeart(human, -cnt, logType)
	end

	local newCnt = (human.db.bag[id] or 0) - cnt
	if newCnt < 0 then assert(nil) end
	if newCnt < 1 then
		newCnt = nil
	end
	human.db.bag[id] = newCnt
		
	if not noSend then
		sendChange(human, id)
	end	
	Log.write(Log.LOGID_OSS_ITEM, human.db._id, human.db.account, human.db.name, human.db.lv, 
		LogDefine.DEFINE[logType] + LogDefine.TYPE["item"] , id, -cnt, newCnt or 0)
		
	if itemConfig.subType == ItemDefine.ITEM_SUBTYPE_SUIPIAN or 
		itemConfig.subType == ItemDefine.ITEM_SUBTYPE_SUIPIAN_SKIN then
		RoleSystemLogic.onDot(human, RoleSystemDefine.ROLE_SYS_ID_206)
	end
	
    if id == ItemDefine.ITEM_GREEN_EXP_ID then
		HeroGrowUp.onCallback(human, HeroGrowUp.TASKTYPE18, cnt)
	end	
	return true
end

-- 获得道具数量
function getItemCnt(human, id, isUse)
	if id == ItemDefine.ITEM_JINBI_ID and not isUse then 
		return human.db.jinbi or 0
	elseif id == ItemDefine.ITEM_ZUANSHI_ID and not isUse then 
		return human.db.zuanshi or 0
    elseif id == ItemDefine.ITEM_FRIEND_ID and not isUse then 
		return human.db.friendHeart or 0
	end
	return human.db.bag[id] or 0
end


-- 判断道具数量
function checkItemCnt(human, id, cnt)
	if id == ItemDefine.ITEM_ZUANSHI_ID then
		return ObjHuman.checkRMB(human,cnt)
	end 

	if getItemCnt(human, id) < cnt then
		local name = ItemDefine.getValue(id,"name")
		return Broadcast.sendErr(human,Util.format(Lang.COMMON_NO_ITEM, name))
	end

	return true
end

-- 特殊不进背包的道具
function handlerSpObj(human, itemID, itemCnt, logType)
    local itemConfig = ItemExcel[itemID]
    if not itemConfig then return end

    if itemConfig.subType ~= ItemDefine.ITEM_SUBTYPE_SPOBJ then
    	return
    end

	local cmdstr = itemConfig.cmd and itemConfig.cmd[1]
	if cmdstr and ItemLogic.cmd[cmdstr] then
		ItemLogic.onlyuse(human, itemID, itemCnt, logType, true)
            
        -- 根据道具触发红点
	    checkDotByID(human,itemID)
	end	

	if ItemDefine.checkIsWave(LogDefine.DEFINE[logType]) then
		sendRoll(human, itemID, itemCnt)
	end	
	return true
end

-- 符文
function handleFuwen(human, itemID, itemCnt, logType)
    if not FuwenExcel[itemID] then return end
	
	FuwenLogic.add(human, itemID, itemCnt, logType)
	if ItemDefine.checkIsWave(LogDefine.DEFINE[logType]) then
		sendRoll(human, itemID, itemCnt)
	end	
	return true
end

-- 装备增加
function handleEquipAdd(human, itemID, itemCnt, logType, otherData)
    if not EquipExcel[itemID] then return end
	
	EquipLogic.addEquip(human, itemID, itemCnt, logType, otherData)
    
    if EquipExcel[itemID].mainType == ItemDefine.MAINTYPE_EQUIP then
        if EquipExcel[itemID].level == 14 then
            ChengjiuLogic.onCallback(human,ChengjiuDefine.CJ_TASK_TYPE_24,itemCnt)
        end
    end

	if ItemDefine.checkIsWave(LogDefine.DEFINE[logType]) then
		sendRoll(human, itemID, itemCnt)
	end	
	return true
end

---------------------------- msg --------------------------------
-- 发送背包道具
function sendBagList(human)
	local msgRet = Msg.gc.GC_BAG_LIST	
	msgRet.list[0] = 0
	for itemID, itemCnt in pairs(human.db.bag) do
		msgRet.list[0] = msgRet.list[0] + 1
		local net = msgRet.list[msgRet.list[0]]
		Grid.makeItem(net, itemID, itemCnt, nil,nil,nil, Grid.getOpflagAtBag(itemID))
		if msgRet.list[0] >= ItemDefine.PAGE_LIST_COUNT then
			Msg.send(msgRet, human.fd)
			msgRet.list[0] = 0
		end
	end	
	if msgRet.list[0] > 0 then
		Msg.send(msgRet, human.fd)
	end
end

-- 改变
function sendChange(human, itemID, isAdd)
	local msgRet = Msg.gc.GC_ITEM_BAG_CHANGE
	local itemCnt = human.db.bag[itemID] or 0
	msgRet.itemID = itemID	
	msgRet.itemCnt = itemCnt
	msgRet.itemData[0] = 0
	if isAdd == true then
		msgRet.itemData[0] = 1
		Grid.makeItem(msgRet.itemData[1], itemID, itemCnt, nil,nil,nil, Grid.getOpflagAtBag(itemID))
	end	
	Msg.send(msgRet, human.fd)
end

-- 滚动
function sendRoll(human, itemID, itemCnt)
    
	--[[local msgRet = Msg.gc.GC_ITEM_BAG_ROLL
	msgRet.itemData[0] = 1
	Grid.makeItem(msgRet.itemData[1], itemID, itemCnt)
	Msg.send(msgRet, human.fd)]]
end

-- 通用道具获得面板 list = {...}
function sendItemGetList(human, list, logStr)
	if not list or not next(list) then return end
	if list[1] and list[1][1] then
		sendItemGetList1(human, list, logStr)
	else
		sendItemGetList2(human, list, logStr)
	end
end

-- 通用道具获得面板 list = {[1]={id,cnt},[2]={id2,cnt2}...}
function sendItemGetList1(human, list, logStr)
	if not list or not next(list) then return end
	local msgRet = Msg.gc.GC_ITEM_GET_LIST
	msgRet.popupType = ItemDefine.checkIsWave(LogDefine.DEFINE[logStr]) and 1 or 0
    local len = math.min(#list, #msgRet.list)
    local cnt = 0
	cnt = EquipLogic.makeEquipItem(human, msgRet.list, cnt)
	for i=1,len do
		if cnt >= #msgRet.list then
			break
		 end
		local itemID = list[i][1]
		local itemCnt = list[i][2]
        if not ItemDefine.isEquip(itemID) then
           cnt = cnt + 1
		   Grid.makeItem(msgRet.list[cnt], itemID, itemCnt)
        end
	end

	if cnt > 0 then
        msgRet.list[0] = cnt
		Msg.send(msgRet,human.fd)
	end
end

-- 通用道具获得面板2 list = {[id]=cnt,[id2]=cnt2}
function sendItemGetList2(human, list, logStr)
	if not list or not next(list) then return end
	local msgRet = Msg.gc.GC_ITEM_GET_LIST
	msgRet.popupType = ItemDefine.checkIsWave(LogDefine.DEFINE[logStr]) and 1 or 0
	msgRet.list[0] = 0 
	local cnt = 0
	cnt = EquipLogic.makeEquipItem(human, msgRet.list, cnt)
	for itemID, itemCnt in pairs(list) do
		if cnt >= #msgRet.list then
			break
		end

        if not ItemDefine.isEquip(itemID) then
			cnt = cnt + 1
		   	Grid.makeItem(msgRet.list[cnt], itemID, itemCnt)
        end
	end

	--Msg.trace(msgRet)
	if cnt > 0 then
        msgRet.list[0] = cnt
		Msg.send(msgRet,human.fd)
	end
end

-- 通用道具获得面板2 list = {[id]=cnt,[id2]=cnt2}
function sendItemGetList3(human, list, logStr)
	if not list or not next(list) then return end
	local msgRet = Msg.gc.GC_ITEM_GET_LIST
	msgRet.popupType = ItemDefine.checkIsWave(LogDefine.DEFINE[logStr]) and 1 or 0
	msgRet.list[0] = 0
	local cnt = 0
    cnt = EquipLogic.makeEquipItem(human, msgRet.list, cnt)
	for i = 1, #list do
        local items = list[i]
        for itemID, itemCnt in pairs(items) do
           if cnt >= #msgRet.list then
		      break
		   end
           if not ItemDefine.isEquip(itemID) then
			  cnt = cnt + 1
		      Grid.makeItem(msgRet.list[cnt], itemID, itemCnt)
           end
        end
	end

	if  cnt > 0 then
        msgRet.list[0] = cnt
		Msg.send(msgRet,human.fd)
	end
end

-- 相同的道具自动叠加一起
local SAME_ITEMS1 = {}
local SAME_ITEMS2 = {}
function sameItemTogether(list)
	if not list or not next(list) then return end
	for k in pairs(SAME_ITEMS1) do 
		SAME_ITEMS1[k] = nil
	end
	for k in pairs(SAME_ITEMS2) do
		SAME_ITEMS2[k] = nil
	end

	for _, item in ipairs(list) do
		local itemID = item[1]
		local itemCnt = item[2]

        -- 装备符文不能叠加
        if not ItemDefine.isEquip(itemID) and not ItemDefine.isFuwen(itemID) then
		   SAME_ITEMS1[itemID] = (SAME_ITEMS1[itemID] or 0) + itemCnt
        end
	end
	for itemID, itemCnt in pairs(SAME_ITEMS1) do
		SAME_ITEMS2[#SAME_ITEMS2 + 1] = {itemID, itemCnt} 
	end
	return SAME_ITEMS2, SAME_ITEMS1
end

-- 背包道具出售
function itemSell(human, itemID, itemCnt)
	if itemCnt < 1 then return end	
	local itemConfig = ItemDefine.getConfig(itemID)
	if not itemConfig then return end
	if not itemConfig.price then return end

	local saleItemID = itemConfig.price[1]
	local saleItemCnt = itemConfig.price[2]
	if not saleItemCnt or saleItemCnt < 1 then return end -- 不能出售	

	local bagCnt = getItemCnt(human, itemID)
	if bagCnt < itemCnt then return end

	local itemCntAdd = math.floor(saleItemCnt * itemCnt)
	delItem(human, itemID, itemCnt, "item_sale")
    addItem(human, saleItemID, itemCntAdd, "item_sale")
	
    local list = {}
    list[1] = { [1] = saleItemID, [2]= itemCntAdd }
    sendItemGetList(human, list)


	local msgRet = Msg.gc.GC_BAG_ITEM_SELL
	msgRet.id = itemID
	msgRet.cnt = itemCnt
	Msg.send(msgRet, human.fd)
end

-- 装备道具出售
function equipSell(human, bagIndex)
    local equipGrid = human.db.equipBag[bagIndex]
    if not equipGrid then return end

    local itemConfig = ItemDefine.getConfig(equipGrid.id)
    if not itemConfig then return end
    if not itemConfig.price then return end

    local saleItemID = itemConfig.price[1]
    local saleItemCnt = itemConfig.price[2]
    if not saleItemCnt or saleItemCnt < 1 then return end

    EquipLogic.delEquip(human, bagIndex, "equip_sale")
    local itemCntAdd = saleItemCnt
    addItem(human, saleItemID, itemCntAdd, "equip_sale")


    sendItemGetList(human, {[1]=itemConfig.price})
end


-- 装备道具出售
function equipSellByQuality(human, qualityStr)
    local qualityList = Util.split(qualityStr, ",", true)
    local len = #qualityList
    if len <= 0 or len > 4 then return end

    local outItems = {}
    for i = 1, #qualityList do
        local quality = qualityList[i]
        for k, equipGrid in pairs(human.db.equipBag) do

           if equipGrid.quality == quality then

            local itemConfig = ItemDefine.getConfig(equipGrid.id)
            if not itemConfig then assert() end
            if not itemConfig.price then assert() end

            local saleItemID = itemConfig.price[1]
            local saleItemCnt = itemConfig.price[2]
            if not saleItemCnt or saleItemCnt < 1 then assert() end

            EquipLogic.delEquip(human, k, "equip_sale", true)
            local itemCntAdd = saleItemCnt
            addItem(human, saleItemID, itemCntAdd, "equip_sale")

            outItems[saleItemID] = outItems[saleItemID] or 0
            outItems[saleItemID] = outItems[saleItemID] + itemCntAdd

           end
        end
    end
    sendItemGetList(human, outItems)
    -- 出售成功
    local msgRet = Msg.gc.GC_BAG_EQUIP_SELL_QUALITY
    Msg.send(msgRet,human.fd)
end

-- 道具购买查询
function queryItemBuy(human, id)	
	local config = ItemBuyExcel[id]
	if not config then return end

	local msgRet = Msg.gc.GC_ITEM_BUY_QUERY
	msgRet.id = id 
	msgRet.item[0] = 1
	Grid.makeItem(msgRet.item[1], id , 1)
	msgRet.canBuy[0] = 2
	msgRet.canBuy[1] = config.cnt1
	msgRet.canBuy[2] = config.cnt2
	msgRet.need[0] = 0
	for _, item in ipairs(config.need1) do
		msgRet.need[0] = msgRet.need[0] + 1
		Grid.makeItem(msgRet.need[msgRet.need[0]], item[1], item[2])
	end	
	msgRet.needTwo[0] = 0
	for _, item in ipairs(config.need2) do
		msgRet.needTwo[0] = msgRet.needTwo[0] + 1
		Grid.makeItem(msgRet.needTwo[msgRet.needTwo[0]], item[1], item[2])
	end	
	--Msg.trace(msgRet)
	Msg.send(msgRet,human.fd)
end

-- 购买道具
function buyItem(human, id, buyCnt, cnt)
	local config  = ItemBuyExcel[id]
	if not config then return end

	local needList = nil
	if config.cnt1 == buyCnt then
		needList = config.need1
	elseif config.cnt2 == buyCnt then
		needList = config.need2
	end
	if not needList then return end
	if cnt < 1 then return end

	-- 判断消耗
	for _, item in ipairs(needList) do
		if not checkItemCnt(human, item[1], item[2] * cnt) then
			return
		end
	end

	-- 某些购买日志类型特殊
	local logType = "item_buy"
	if id == ItemDefine.ITEM_ABS_DRAW_LONGZHU_ID then
		logType = "item_buy_dragong"
	end

	-- 扣除道具
	for _, item in ipairs(needList) do
		delItem(human, item[1], item[2] * cnt, logType)
	end
	addItem(human, id, buyCnt * cnt, logType)
	Broadcast.sendErr(human, Lang.ITEM_BUY_SUCCESS) 

	local msgRet = Msg.gc.GC_ITEM_BUY
	msgRet.id = id 
	Msg.send(msgRet, human.fd)
end

function sendCommonBuyQuery(human, itemID)
	local config  = ItemComonBuyExcel[itemID]
	if not config then return end	

	local msgRet = Msg.gc.GC_ITEM_COMMON_BUY_QUERY
	Grid.makeItem(msgRet.item, itemID, 1)
	msgRet.price = config.price
	Msg.send(msgRet, human.fd)
end

function commonBuy(human, itemID, itemCnt)
	if itemCnt < 1 then return end
	local config  = ItemComonBuyExcel[itemID]
	if not config then return end	

	local cost = config.price * itemCnt
	if not ObjHuman.checkRMB(human, cost) then
		return
	end	
	ObjHuman.decZuanshi(human, -cost, "item_buy", itemID, itemCnt)
	addItem(human, itemID, itemCnt, "item_buy")

	local msgRet = Msg.gc.GC_ITEM_COMMON_BUY
	msgRet.itemID = itemID
	Msg.send(msgRet, human.fd)
end

function isDot(human)
	for itemID, itemCnt in pairs(human.db.bag) do
		local itemConfig = ItemExcel[itemID]
		if itemConfig then
			if itemConfig.subType == ItemDefine.ITEM_SUBTYPE_SUIPIAN or 
				itemConfig.subType == ItemDefine.ITEM_SUBTYPE_SUIPIAN_SKIN then
				if itemCnt >= itemConfig.fullCnt then
					return true
				end
			end
		end
	end
	return false
end
